<?php if(!defined('WDK_PATH')) exit('No direct script access allowed');
/**
 * @since 2011. 9. 30
 * @author kinuz
 */
class Hp_Passwd 
{
	protected
		/******************************************************/
		//	
		/******************************************************/
		$max_lenth		= 15,		//	
		$min_lenth		= 6,		//	
		$hint_lenth		= 3,		//	
		$encrypt_lenth	= 48,		//	
		$chars			= array();	//		 	
		
	/**
	 * 	생성자
	 * @since 2011. 9. 30
	 * @author kinuz
	 */
	function __construct($data=array())
	{
		$this->chars = array(35,36,37,38,42,43,45,95,61,124);
		$this->chars = array_merge($this->chars, range(48, 57));
		$this->chars = array_merge($this->chars, range(65, 90));
		$this->chars = array_merge($this->chars, range(97, 122));
	}
	
	/**
	 *	데이터 초기화 시키기
	 * @since 2011. 9. 30
	 * @author kinuz
	 */
	public function __init($data)
	{
		parent::__init($data);
	}
	
	public function encrypt($str, $code='', $shuffle=0)
	{
		if($this->isEncryptable($str) == false)	return;
		if(strlen($str) > $this->max_lenth)
		{
			throw new \PasswdLenthException("max {$this->max_lenth} chars.");
		}
		if(strlen($str) < $this->min_lenth)
		{
			throw new \PasswdLenthException("min {$this->min_lenth} chars.");
		}
		
		if($code == '' )	$code	= $this->rc(2);
		if($shuffle == 0 )	$shuffle= rand(1,9);
		
		$pwd = $code.$shuffle.substr($str, 0, $this->hint_lenth);
		$pwd.= str_pad(strlen($str), 2, '0', STR_PAD_LEFT);
		$pwd.= $this->shuffle($str, $code, $shuffle);
		return $pwd;
	}
	
	public function decrypt($str)
	{
		if($this->isDecryptable($str) == false) return $str;
		if($this->isEncrypted($str) == false)
		{
			throw new \PasswdLenthException("비밀번호는 형식에 맞지 않습니다.");
		}
		$hint = substr($str, 3, $this->hint_lenth);
		$length = substr($str, 3+$this->hint_lenth, 2);
		return str_pad($hint, $length, '*', STR_PAD_RIGHT);			
	}
	
	public function isEqual($str1, $str2)
	{
		if($this->isEncrypted($str1))
		{
			$code		= substr($str1, 0, 2);
			$shuffle	= substr($str1, 2, 1);
			return $str1 == $this->encrypt($str2, $code, $shuffle);
		}
		else
		{
			$code		= substr($str2, 1, 2);
			$shuffle	= substr($str2, 0, 1);
			return $this->encrypt($str1, $code, $shuffle) == $str2;
		}
	}
	
	private function rc($i=1)
	{
		if($i == 0) return '';
		return $this->rc(--$i).chr($this->chars[rand(0, count($this->chars))]);
	}
	
	private function shuffle($str, $code, $i=1)
	{
		if($i == 0) return '';
		return sha1($str.$code);
	}
	
	public function isEncrypted($str)
	{
		return (strlen($str) == $this->encrypt_lenth
				|| preg_match("/(.*){3}[0-9]{1}[*]+/", $str));
	}
	
	public function isEncryptable($str)
	{
		return (strlen($str) != $this->encrypt_lenth
				&&	strlen($str) >= $this->min_lenth
				&&	! preg_match("/(.*){3}[0-9]{1}[*]+/", $str)
				);
	}
	
	public function isDecryptable($str)
	{
		return strlen($str) == $this->encrypt_lenth;
	}
}